﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SbsSW.SwiPlCs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Adventure.Model
{
    internal class Character
    {
        #region Constructors
        public Character(Rectangle bounds)
        {
            _bounds = bounds;
            _lastBounds = bounds;
        }

        #endregion

        #region Private Fields

        private Rectangle _bounds;
        private Rectangle _lastBounds;
        private Texture2D _texture;
        private bool _dead = false;
        private int _lastUpdateTime = 0;

        #endregion

        #region Internal Methods

        internal void Initialize()
        {
            _texture = GraphicsResources.ContentManager.Load<Texture2D>(@"Textures\Rectangle");
        }

        internal void Update(GameTime gameTime, Scenario currentScenario, int time)
        {
            using (var positionsQuery = new PlQuery(string.Format("posicao(X, Y, personagem, {0})", time)))
            {
                var position = positionsQuery.SolutionVariables.First();
                var x = Convert.ToInt32(position["X"].ToString()) - (int)currentScenario.Offset.X;
                var y = Convert.ToInt32(position["Y"].ToString()) - (int)currentScenario.Offset.Y;
                _bounds = new Rectangle(x, y, _bounds.Width, _bounds.Height);
            }

            using (var deadQuery = new PlQuery(string.Format("morto(personagem, {0}, S)", time)))
            {
                var dead = deadQuery.SolutionVariables.First();
                _dead = dead["S"].ToString() == "1" ? true : false;
            }

            var keyboardState = Keyboard.GetState();

            var delta = Vector2.Zero;
            var keys = keyboardState.GetPressedKeys();

            if (keys.Contains(Keys.Right))
                delta.X += 1;
            if (keys.Contains(Keys.Left))
                delta.X -= 1;
            if (keys.Contains(Keys.Up))
                delta.Y -= 1;
            if (keys.Contains(Keys.Down))
                delta.Y += 1;

            if (delta != Vector2.Zero)
                PlQuery.PlCall(string.Format("asserta(movimentar({0}, {1}, personagem, {2}))", delta.X, delta.Y, time));

            if (keys.Contains(Keys.Space))
                PlQuery.PlCall(string.Format("asserta(largar({0}))", time));
        }

        internal void UpdateData(Scenario currentScenario, Scenario lastCurrentScenario, int time)
        {
            PlQuery.PlCall(string.Format("retract(posicao({0}, {1}, personagem, {2}))", _lastBounds.X + lastCurrentScenario.Offset.X, _lastBounds.Y + lastCurrentScenario.Offset.Y, _lastUpdateTime));
            PlQuery.PlCall(string.Format("asserta(posicao({0}, {1}, personagem, {2}))", _bounds.X + currentScenario.Offset.X, _bounds.Y + currentScenario.Offset.Y, time));

            PlQuery.PlCall(string.Format("retract(morto(personagem, {0}, {1}))", _lastUpdateTime, _dead ? "1" : "0"));
            PlQuery.PlCall(string.Format("asserta(morto(personagem, {0}, {1}))", time, _dead ? "1" : "0"));

            _lastBounds = _bounds;
            _lastUpdateTime = time;
        }

        internal void Draw(GameTime gameTime)
        {
            GraphicsResources.SpriteBatch.Begin();

            //GraphicsResources.SpriteBatch.Draw(_texture, _bounds, new Color(210, 210, 64));
            GraphicsResources.SpriteBatch.Draw(_texture, _bounds, Color.Black);

            GraphicsResources.SpriteBatch.End();
        }

        #endregion
    }
}
